package com.xusheng.cli.controller.user;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xusheng.cli.common.base.MyPage;
import com.xusheng.cli.common.base.Result;
import com.xusheng.cli.common.constant.Constant;
import com.xusheng.cli.entity.commentModule.Comment;
import com.xusheng.cli.entity.frontUserModule.FrontUser;
import com.xusheng.cli.entity.shareModule.Share;
import com.xusheng.cli.entity.taskRecordModule.TaskRecord;
import com.xusheng.cli.entity.videoModule.Video;
import com.xusheng.cli.req.FavoritesQueryReq;
import com.xusheng.cli.req.UpdateAccountReq;
import com.xusheng.cli.req.UpdateInfoReq;
import com.xusheng.cli.req.UpdatePasswordReq;
import com.xusheng.cli.service.*;
import com.xusheng.cli.tools.CurrentPlayerUserUtil;
import com.xusheng.cli.tools.SMSVerificationCode;
import com.xusheng.cli.tools.StpPlayerUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户信息相关接口
 *
 * @author lyh
 * @since 2023-04-27 15:36
 */
@Slf4j
@RestController
@RequestMapping("/user/v1/user")
public class FrontUserController {

    @Resource
    private FrontUserService frontUserService;
    @Resource
    private ShareService shareService;
    @Resource
    private WatchingRecordService watchingRecordService;
    @Resource
    private FavoritesService favoritesService;
    @Resource
    private CommentController commentController;
    @Resource
    private TaskRecordService taskRecordService;
    @Resource
    private VipLevelService vipLevelService;
    @Resource
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 通过主键查询单条数据
     *
     * @return 单条数据
     * @author 王鹤然
     * @since 2023-07-03 12:38:12
     */
    @GetMapping("qetUserInfo")
    public Result<FrontUser> qetUserInfo() {
        Long id = CurrentPlayerUserUtil.getUserId();
        FrontUser user = frontUserService.getById(id);
        user.setVipLevel(vipLevelService.getById(user.getPromotionLevel()));
        return Result.success(user);
    }

    /**
     * 更新用户信息
     *
     * @param req 更新信息
     * @return 返回结果
     */
    @PutMapping("/updateInfo")
    public Result<Object> updateInfo(@Validated @RequestBody UpdateInfoReq req) {
        long userId = CurrentPlayerUserUtil.getUserId();
        FrontUser update = frontUserService.getById(userId);
        update.setId(userId);
        update.setEmail(req.getEmail());
        update.setPhone(req.getPhone());
        return Result.isSuccess(frontUserService.updateById(update));
    }

    /**
     * 修改手机号
     *
     * @param req
     * @return
     */
    @PutMapping("/updateAccount")
    public Result<Object> updateAccount(@Validated @RequestBody UpdateAccountReq req) {
        long userId = CurrentPlayerUserUtil.getUserId();
        FrontUser update = frontUserService.getById(userId);
        // 验证码
        String key = SMSVerificationCode.M_REGIST_KEY + req.getAccount();
        String c = redisTemplate.opsForValue().get(key);
        log.info("key={}, redis-code = {}, user-code={}", key, c, req.getSmsCode());
        if (StrUtil.isBlank(c) || !c.equals(req.getSmsCode())) {
            return Result.error("短信验证码不正确");
        }
        redisTemplate.delete(key);
        long count = frontUserService.lambdaQuery()
                .eq(FrontUser::getAccount, req.getAccount())
                .count();
        if (count > 0) {
            return Result.error("账号名已存在");
        }
        update.setId(userId);
        update.setAccount(req.getAccount());
        boolean b = frontUserService.updateById(update);
        StpPlayerUtil.getSession().set(Constant.PLAYER, update);
        return Result.isSuccess(b);
    }

    /**
     * 修改密码
     *
     * @param req 新密码
     * @return 返回结果
     */
    @PutMapping("/updatePwd")
    public Result<Object> updatePassword(@Validated @RequestBody UpdatePasswordReq req) {
        long userId = CurrentPlayerUserUtil.getUserId();
        FrontUser update = frontUserService.getById(userId);
        if (req.getForgetPassword()) {
            // 验证码
            String key = SMSVerificationCode.M_REGIST_KEY + req.getAccount();
            String c = redisTemplate.opsForValue().get(key);
            log.info("key={}, redis-code = {}, user-code={}", key, c, req.getSmsCode());
            if (StrUtil.isBlank(c) || !c.equals(req.getSmsCode())) {
                return Result.error("短信验证码不正确");
            }
            redisTemplate.delete(key);
        } else {
            String password = update.getPassword();
            boolean b = DigestUtil.bcryptCheck(req.getOriginPassword(), password);
            if (!b) {
                return Result.error("原密码错误");
            }
        }
        update.setId(userId);
        update.setPassword(DigestUtil.bcrypt(req.getPassword()));
        boolean b = frontUserService.updateById(update);
        StpPlayerUtil.getSession().set(Constant.PLAYER, update);
        return Result.isSuccess(b);
    }

    /**
     * 退出登录
     *
     * @return
     */
    @GetMapping("/signOut")
    public Result<Object> signOut() {
        StpPlayerUtil.logout();
        return Result.success();
    }

    /**
     * 签到
     *
     * @return
     */
    @PostMapping("/sign")
    public Result<Object> sign() {
        Long userId = CurrentPlayerUserUtil.getUserId();
        FrontUser frontUser = frontUserService.getById(userId);
        frontUser.setTodaySign(true);
        Share config = shareService.getOne(new QueryWrapper<>());
        Integer signGold = config.getSignGold();
        frontUser.setGold(frontUser.getGold() + signGold);
        return Result.isSuccess(frontUserService.updateById(frontUser));
    }

    /**
     * 任务中心
     *
     * @return
     */
    @GetMapping("/taskCenter")
    public Result<Object> taskCenter() {
        Map<String, Object> taskMap = new HashMap<>();
        Long userId = CurrentPlayerUserUtil.getUserId();
        FrontUser user = frontUserService.getById(userId);
        // 观看10部影片
        MyPage<Video> recordList = watchingRecordService.watchingRecordList(userId, 1, 10, 9);
        if (recordList.getRecords().size() >= 10) {
            taskMap.put("record", checkRecord("record"));
        } else {
            taskMap.put("record", 1);
        }
        // 收藏5部影片
        FavoritesQueryReq favoritesQueryReq = new FavoritesQueryReq();
        favoritesQueryReq.setUserId(userId);
        favoritesQueryReq.setSize(10);
        MyPage<Video> favoriteList = favoritesService.favoritesPage(favoritesQueryReq, true);
        if (favoriteList.getRecords().size() >= 5) {
            taskMap.put("favorite", checkRecord("favorite"));
        } else {
            taskMap.put("favorite", 1);
        }
        // 点击广告
        if (user.getClickAd()) {
            taskMap.put("ad", checkRecord("ad"));
        } else {
            taskMap.put("ad", 1);
        }
        // 评论一部影片
        Comment comment = new Comment();
        comment.setStartTime(LocalDateTime.now().with(LocalTime.MIN));
        comment.setEndTime(LocalDateTime.now().with(LocalTime.MAX));
        Result<List<Comment>> commentList = commentController.queryAll(comment);
        if (commentList.getData().size() >= 1) {
            taskMap.put("comment", checkRecord("comment"));
        } else {
            taskMap.put("comment", 1);
        }
        //保存推广二维码
        if (user.getSaveQrcode() != null && user.getSaveQrcode()) {
            TaskRecord record = taskRecordService.getOne(new LambdaQueryWrapper<>(new TaskRecord())
                    .eq(TaskRecord::getType, "code")
                    .eq(TaskRecord::getUserId, CurrentPlayerUserUtil.getUserId()));
            if (record != null) {
                taskMap.put("code", 3);
            } else {
                taskMap.put("code", 2);
            }
        } else {
            taskMap.put("code", 1);
        }
        return Result.success(taskMap);
    }

    public int checkRecord(String type) {
        TaskRecord record = taskRecordService.getOne(new LambdaQueryWrapper<>(new TaskRecord())
                .eq(TaskRecord::getType, type)
                .eq(TaskRecord::getUserId, CurrentPlayerUserUtil.getUserId())
                .gt(TaskRecord::getCreateTime, LocalDateTime.now().with(LocalTime.MIN))
                .lt(TaskRecord::getCreateTime, LocalDateTime.now().with(LocalTime.MAX)));
        if (record != null) {
            return 3;
        } else {
            return 2;
        }
    }

    /**
     * 完成任务领去金币
     *
     * @return
     */
    @PostMapping("/completeTask")
    public Result<Object> completeTask(@RequestBody TaskRecord taskRecord) {
        // 添加任务记录
        taskRecord.setUserId(CurrentPlayerUserUtil.getUserId());
        taskRecordService.save(taskRecord);
        FrontUser user = frontUserService.getById(CurrentPlayerUserUtil.getUserId());
        user.setGold(user.getGold() + 1);
        return Result.isSuccess(frontUserService.updateById(user));
    }

    @GetMapping("/myPromotion")
    public Result<List<FrontUser>> myPromotion() {
        //获取我的邀请码
        String inviteCode = CurrentPlayerUserUtil.getCurrentUser().getInviteCode();
        List<FrontUser> list = frontUserService.getMyPromotionList(inviteCode);
        return Result.success(list);
    }
}
